package com.lingdong.onlinejudge.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lingdong.onlinejudge.common.ErrorCode;
import com.lingdong.onlinejudge.common.PageRequest;
import com.lingdong.onlinejudge.exception.BusinessException;
import com.lingdong.onlinejudge.mapper.UserMapper;
import com.lingdong.onlinejudge.mapper.UserTeamMapper;
import com.lingdong.onlinejudge.model.dto.team.*;
import com.lingdong.onlinejudge.model.entity.Team;
import com.lingdong.onlinejudge.model.entity.User;
import com.lingdong.onlinejudge.model.entity.UserTeam;
import com.lingdong.onlinejudge.model.vo.team.TeamVo;
import com.lingdong.onlinejudge.model.vo.user.UserVo;
import com.lingdong.onlinejudge.service.AuthService;
import com.lingdong.onlinejudge.service.TeamService;
import com.lingdong.onlinejudge.mapper.TeamMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 队伍相关
 * @author lzw
*/

@Service
public class TeamServiceImpl extends ServiceImpl<TeamMapper, Team>
    implements TeamService{

    @Resource
    private TeamMapper teamMapper;

    @Resource
    private AuthService authService;

    @Resource
    private UserTeamMapper userTeamMapper;

    @Resource
    private UserMapper userMapper;


    /**
     * 创建队伍
     * @param teamCreateDto 队伍信息
     * @return 结果
     */
    @Override
    @Transactional
    public Boolean createTeam(TeamCreateDto teamCreateDto, String token) {
        String teamName = teamCreateDto.getTeamName();
        Integer isExamine = teamCreateDto.getIsExamine();
        Integer teamPeople = teamCreateDto.getTeamPeople();
        if (StringUtils.isAnyBlank(teamName) || teamName.length() > 10){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"队伍名称不符合要求");
        }
        if (isExamine == null || teamPeople == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        if (teamPeople < 3 || teamPeople > 20){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"队伍人数不符合要求");
        }
        if (isExamine != 0 && isExamine != 1){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"审核状态不符合要求");
        }
        // 减去队长位置
        teamCreateDto.setTeamPeople(teamPeople - 1);
        Team team = new Team();
        BeanUtils.copyProperties(teamCreateDto, team);
        UserVo userInfo = authService.getUserInfo(token);
        team.setTeamLeader(userInfo.getId());
        boolean save = this.save(team);
        if (!save){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
        return true;
    }

    /**
     * 获取队伍邀请码
     * @param teamCodeDto 队伍信息
     * @return 邀请码
     */
    @Override
    public String getTeamCode(TeamCodeDto teamCodeDto) {
        Long id = teamCodeDto.getId();
        if (id == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        Team team = teamMapper.selectOne(queryWrapper);
        if (team == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"队伍不存在");
        }
        // 生成8位随机数
        String code = String.valueOf(ThreadLocalRandom.current().nextInt(10000000, 100000000));
        team.setTeamCode(Integer.parseInt(code));
        int i = 0;
        try {
            i = teamMapper.updateById(team);
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        if (i == 0){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return code;
    }

    /**
     * 获取队伍信息
     * @param id 队伍id
     * @return 队伍信息
     */
    @Override
    public TeamVo getTeam(Long id) {
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        Team team = teamMapper.selectOne(queryWrapper);
        if (team == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"队伍不存在");
        }
        TeamVo teamVo = new TeamVo();
        BeanUtils.copyProperties(team, teamVo);
        QueryWrapper<UserTeam> userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.eq("team_id", id);
        // 查询审核状态为通过的
        userTeamQueryWrapper.eq("examine_status", 1);
        List<UserTeam> userTeams = userTeamMapper.selectList(userTeamQueryWrapper);
        if (userTeams == null || userTeams.size() == 0){
            teamVo.setTeamMember(Collections.emptyList());
            return teamVo;
        }
        List<UserVo> teamMember = teamVo.getTeamMember();
        if (teamMember == null){
            teamMember = new ArrayList<>();
        }
        // 查询关联的用户
        for (UserTeam userTeam : userTeams) {
            UserVo userVo = new UserVo();
            Long userId = userTeam.getUserId();
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.eq("id", userId);
            User user = userMapper.selectOne(userQueryWrapper);
            BeanUtils.copyProperties(user, userVo);
            teamMember.add(userVo);
        }
        teamVo.setTeamMember(teamMember);
        return teamVo;
    }

    /**
     * 加入队伍
     * @param teamJoinDto 队伍信息
     * @return 结果
     */
    @Override
    public Boolean joinTeam(TeamJoinDto teamJoinDto, String token) {
        String teamCode = teamJoinDto.getTeamCode();
        if (StringUtils.isBlank(teamCode) || teamCode.length() != 8){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"邀请码格式不符合要求");
        }
        UserVo userInfo = authService.getUserInfo(token);
        QueryWrapper<Team> teamQueryWrapper = new QueryWrapper<>();
        teamQueryWrapper.eq("team_code", teamCode);
        Team team = teamMapper.selectOne(teamQueryWrapper);
        if (team == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"队伍不存在");
        }
        // 判断队伍人数是否已满
        QueryWrapper<UserTeam> userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.eq("team_id", team.getId());
        Long count = userTeamMapper.selectCount(userTeamQueryWrapper);
        if (count + 1 > team.getTeamPeople()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"队伍人数已满");
        }
        // 判断是否已加入队伍
        userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.eq("team_id", team.getId())
            .eq("user_id", userInfo.getId());
        if (userTeamMapper.selectOne(userTeamQueryWrapper) != null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"你已加入队伍");
        }
        UserTeam userTeam = new UserTeam();
        userTeam.setTeamId(team.getId());
        userTeam.setUserId(userInfo.getId());
        // 队伍加入不需要审核
        if (team.getIsExamine() == 0){
            // 将记录设置为审核通过
            userTeam.setExamineStatus(1);
        }
        int insert = userTeamMapper.insert(userTeam);
        if (insert == 0){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return true;
    }

    /**
     * 查询队伍列表
     * @param teamListDto 队伍信息
     * @return 队伍列表
     */
    @Override
    public List<Team> queryTeamList(TeamListDto teamListDto) {
        String teamName = teamListDto.getTeamName();
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(teamName), "team_name", teamName);
        return teamMapper.selectList(queryWrapper);
    }

    /**
     * 查询队伍列表分页
     * @param teamPageDto 队伍信息
     * @return 队伍列表
     */
    @Override
    public Page<Team> queryTeamByPage(TeamPageDto teamPageDto) {
        PageRequest page = teamPageDto.getPage();
        if (page == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(teamPageDto.getTeamName()), "team_name", teamPageDto.getTeamName());
        return teamMapper.selectPage(new Page<>(page.getCurrent(), page.getPageSize()), queryWrapper);
    }

    /**
     * 解散队伍
     * @param teamId 队伍id
     * @return 结果
     */
    @Override
    @Transactional
    public Boolean dissolveTeam(Long teamId) {
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", teamId);
        int delete = teamMapper.delete(queryWrapper);
        if (delete == 0){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        QueryWrapper<UserTeam> userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.eq("team_id", teamId);
        int flag = userTeamMapper.delete(userTeamQueryWrapper);
        if (flag == 0){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return true;
    }

    /**
     * 退出队伍
     * @param teamExitDto 队伍信息
     * @return 结果
     */
    @Override
    public Boolean exitTeam(TeamExitDto teamExitDto) {
        Long teamId = teamExitDto.getTeamId();
        Long userId = teamExitDto.getUserId();
        if (teamId == null || userId == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 队长不允许直接退出队伍
        QueryWrapper<Team> teamQueryWrapper = new QueryWrapper<>();
        teamQueryWrapper.eq("id", teamId);
        Team team = teamMapper.selectOne(teamQueryWrapper);
        if (team == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍不存在");
        }
        if (team.getTeamLeader().equals(userId)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队长不允许直接退出队伍,请解散队伍");
        }
        QueryWrapper<UserTeam> userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.eq("team_id", teamId)
            .eq("user_id", userId);
        if (userTeamMapper.delete(userTeamQueryWrapper) == 0){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return true;
    }

    /**
     * 审核队伍
     * @param teamExamineDto 队伍信息
     * @return 结果
     */
    @Override
    public Boolean examineTeam(TeamExamineDto teamExamineDto) {
        Long teamId = teamExamineDto.getTeamId();
        Long userId = teamExamineDto.getUserId();
        if (teamId == null || userId == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<UserTeam> userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.eq("team_id", teamId)
                .eq("user_id", userId);
        UserTeam userTeam = userTeamMapper.selectOne(userTeamQueryWrapper);
        if (userTeam == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍不存在");
        }
        Integer examineStatus = teamExamineDto.getExamine();
        if (examineStatus == null ){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "审核状态不能为空");
        }
        if (examineStatus != 2 && examineStatus != 1){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "审核状态错误");
        }
        userTeam.setExamineStatus(examineStatus);
        int update = userTeamMapper.updateById(userTeam);
        if (update == 0){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return true;
    }
}




